package com.cskaoyan.controller.wx;

import com.cskaoyan.bean.BaseRespVo;
import com.cskaoyan.bean.po.MarketAddress;
import com.cskaoyan.bean.po.MarketCart;
import com.cskaoyan.bean.po.MarketCouponUser;
import com.cskaoyan.bean.po.MarketUser;
import com.cskaoyan.bean.wx.cart.UserAvailableCoupon;
import com.cskaoyan.service.wx.WxCartService;
import com.cskaoyan.util.UserIdUtil;
import lombok.Data;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

@RestController
@RequestMapping("wx/cart")
public class WxCartController {

    @Autowired
    WxCartService wxCartService;

    @GetMapping("index")
    public BaseRespVo index() {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            BaseRespVo baseRespVo = new BaseRespVo();
            baseRespVo.setErrno(501);
            baseRespVo.setErrmsg("请先登录");
            return baseRespVo;
        }
        MarketUser primaryPrincipal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = primaryPrincipal.getId();//用于查询的userId,先用1代替
        HashMap<String, Object> map = queryCartById(userId);
        return BaseRespVo.ok(map);
    }

    private HashMap<String, Object> queryCartById(Integer userId) {
        List<MarketCart> marketCarts = wxCartService.queryCartListByUserId(userId);
        Integer checkedGoodsCount = 0;
        BigDecimal goodsAmount = BigDecimal.ZERO;
        BigDecimal checkedGoodsAmount = BigDecimal.ZERO;
        //cartTotal赋值
        for (MarketCart marketCart : marketCarts) {
            goodsAmount = goodsAmount.add(marketCart.getPrice().multiply(new BigDecimal(Integer.toString(marketCart.getNumber()))));
            if (marketCart.getChecked()) {
                checkedGoodsAmount = checkedGoodsAmount.add(marketCart.getPrice().multiply(new BigDecimal(Integer.toString(marketCart.getNumber()))));
                checkedGoodsCount += marketCart.getNumber();
            }
        }
        CartTotal cartTotal = new CartTotal();
        cartTotal.setGoodsCount(marketCarts.size());
        cartTotal.setGoodsAmount(goodsAmount);
        cartTotal.setCheckedGoodsCount(checkedGoodsCount);
        cartTotal.setCheckedGoodsAmount(checkedGoodsAmount);
        HashMap<String, Object> map = new HashMap<>();
        map.put("cartTotal", cartTotal);
        map.put("cartList", marketCarts);
        return map;
    }

    private
    @Data
    class CartTotal {
        Integer goodsCount;

        Integer checkedGoodsCount;

        BigDecimal goodsAmount;

        BigDecimal checkedGoodsAmount;
    }

    @PostMapping("checked")
    public BaseRespVo checked(@RequestBody Map map) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            BaseRespVo baseRespVo = new BaseRespVo();
            baseRespVo.setErrno(501);
            baseRespVo.setErrmsg("请先登录");
            return baseRespVo;
        }
        MarketUser primaryPrincipal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = primaryPrincipal.getId();//用于查询的userId,先用1代替
        List<Integer> productIds = (List<Integer>) map.get("productIds");
        Integer isChecked = (Integer) map.get("isChecked");
        for (Integer productId : productIds) {
            wxCartService.updateChecked(userId, productId, isChecked);
        }
        HashMap<String, Object> stringObjectHashMap = this.queryCartById(userId);
        return BaseRespVo.ok(stringObjectHashMap);
    }

    @PostMapping("add")
    public BaseRespVo add(@RequestBody Map map) {
        Integer goodsId = (Integer) map.get("goodsId");
        Integer number = (Integer) map.get("number");
        Integer productId = (Integer) map.get("productId");
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            BaseRespVo baseRespVo = new BaseRespVo();
            baseRespVo.setErrno(501);
            baseRespVo.setErrmsg("请先登录");
            return baseRespVo;
        }
        MarketUser primaryPrincipal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = primaryPrincipal.getId();
        if (wxCartService.isCartExist(userId, goodsId, productId)) {
            wxCartService.updateCart(userId, goodsId, productId, number);
        } else {
            wxCartService.addCart(userId, goodsId, productId, number);
        }
        //todo
        Integer goodsCount = 0;
        List<MarketCart> marketCarts = wxCartService.queryCartListByUserId(userId);
        for (MarketCart marketCart : marketCarts) {
            goodsCount += marketCart.getNumber();
        }
        return BaseRespVo.ok(goodsCount);
    }

    @GetMapping("goodscount")
    public BaseRespVo goodscount() {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            return BaseRespVo.okAndSuccess(0);
        }
        MarketUser primaryPrincipal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = primaryPrincipal.getId();//用于查询的userId,先用1代替
        Integer goodsCount = 0;
        List<MarketCart> marketCarts = wxCartService.queryCartListByUserId(userId);
        for (MarketCart marketCart : marketCarts) {
            goodsCount += marketCart.getNumber();
        }
        return BaseRespVo.ok(goodsCount);
    }

    /**
     * actualPrice=orderTotalPrice + freightPrice
     * grouponRulesId团购,grouponPrice是market_groupon_rules根据goods_id的id,discount
     * cartId = 0 这里后续修改需要接受一个addressId参数,因为地址选择还需要根据这个来返回,也就是说参数是0的时候是默认地址,不是零的时候根据id来查询地址
     */
    @GetMapping("checkout")
    public BaseRespVo checkout(Integer addressId, Integer userCouponId) {
        //获取userid
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            BaseRespVo baseRespVo = new BaseRespVo();
            baseRespVo.setErrno(501);
            baseRespVo.setErrmsg("请先登录");
            return baseRespVo;
        }
        MarketUser primaryPrincipal = (MarketUser) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = primaryPrincipal.getId();//用于查询的userId,先用1代替
        //checkedAddress是address表的userId默认的地址
        MarketAddress checkedAddress = wxCartService.queryDefaultAddressByUserId(userId);
        //addressId是checkedAddress的id
        Integer responseAddressId = null;
        if (checkedAddress != null) {
            responseAddressId = checkedAddress.getId();
        }
        //如果传入的不是0说明不是使用的默认地址,使用传入的地址再次查找选中的地址信息
        if (addressId != 0) {
            responseAddressId = addressId;
            checkedAddress = wxCartService.queryAddressByAddressId(responseAddressId);
        }
        //checkedGoodsList是cart表的userId&&checked=true的信息-marketcart对象
        List<MarketCart> checkedGoodsList = wxCartService.queryCartListByUserIdAndChecked(userId, true);
        //goodsTotalPrice是根据checkedGoodsList计算总金额
        BigDecimal goodsTotalPrice = BigDecimal.ZERO;
        if (checkedGoodsList != null) {
            for (MarketCart marketCart : checkedGoodsList) {
                goodsTotalPrice = goodsTotalPrice.add(marketCart.getPrice().multiply(new BigDecimal(Integer.toString(marketCart.getNumber()))));
            }
        }
        //couponPrice是优惠券的金额 user拥有的所有coupon中挑一张可用状态下最大的优惠金额返回,要满足总价大于min值
        //先查用户所有的优惠券,日期在开始日期和截至日期之间,状态为0(可用),未删除,用户id匹配的
        List<UserAvailableCoupon> userAvailableCoupons = wxCartService.queryUserCouponByUserId(userId);
        BigDecimal couponPrice = BigDecimal.ZERO;
        //respUserCouponId是market_coupon_user表的id,默认是从可选状态最大的优惠券的id
        Integer respUserCouponId = null;
        //couponId是market_coupon_user的coupon_id
        Integer couponId = null;
        if (userAvailableCoupons.size() != 0) {
            for (UserAvailableCoupon userAvailableCoupon : userAvailableCoupons) {
                BigDecimal discount = userAvailableCoupon.getDiscount();
                BigDecimal min = userAvailableCoupon.getMin();
                //这里判断传入的userCouponId参是不是拥有指定值,userCouponId==0是没有指定优惠券,默认可选的最大优惠券数
                if (userCouponId == 0) {
                    if ((couponPrice.compareTo(discount) < 0) && (goodsTotalPrice.compareTo(min) > 0)) {
                        couponPrice = discount;
                        respUserCouponId = userAvailableCoupon.getId();
                        couponId = userAvailableCoupon.getCouponId();
                    }
                } else if (userCouponId < 0) {
                    //userCouponId < 0是不使用优惠券的情况,将respUserCouponId=null,couponPrice=0,couponId=null
                    respUserCouponId = 0;
                    couponId = 0;
                    couponPrice = BigDecimal.ZERO;
                } else {
                    //这里说明userCouponId有一个指定的id,根据这个id来赋值
                    if (userAvailableCoupon.getId() == userCouponId) {
                        //还要满足购物金额大于优惠券使用金额才可以赋值,否则即便携带了优惠券的id,实际不能用也是返回的0
                        if(userAvailableCoupon.getMin().compareTo(goodsTotalPrice)<0) {
                            respUserCouponId = userCouponId;
                            couponId = userAvailableCoupon.getCouponId();
                            couponPrice = userAvailableCoupon.getDiscount();
                        }else{
                            respUserCouponId = 0;
                            couponId = 0;
                            couponPrice = BigDecimal.ZERO;
                        }
                    }
                }
            }
        }else {
            //说明用户没有优惠券
            respUserCouponId = 0;
            couponId = 0;
        }
        //orderTotalPrice=goodsTotalPrice - couponPrice
        BigDecimal orderTotalPrice = goodsTotalPrice.subtract(couponPrice);
        if (orderTotalPrice.compareTo(BigDecimal.ZERO) < 0) {
            orderTotalPrice = BigDecimal.ZERO;
        }
        //freightPrice是运费,这里写死了为0,也就是actualPrice = orderTotalPrice
        Integer freightPrice = 10;
        if(orderTotalPrice.compareTo(new BigDecimal(88))>0){
            freightPrice = 0;
        }
        //actualPrice=orderTotalPrice + freightPrice
        BigDecimal actualPrice = orderTotalPrice.add(new BigDecimal(freightPrice));
        //grouponRulesId团购,grouponPrice是market_groupon_rules根据goods_id的id,discount
        Integer grouponRulesId = 0;
        Integer grouponPrice = 0;
        //cartId = 0
        Integer cartId = 0;
        //构造返回data
        HashMap<String, Object> map = new HashMap<>();
        map.put("checkedAddress", checkedAddress);
        map.put("checkedGoodsList", checkedGoodsList);
        map.put("grouponRulesId", grouponRulesId);
        map.put("actualPrice", actualPrice);
        map.put("orderTotalPrice", orderTotalPrice);
        map.put("cartId", cartId);
        map.put("userCouponId", respUserCouponId);
        map.put("couponId", couponId);
        map.put("goodsTotalPrice", goodsTotalPrice);
        map.put("addressId", responseAddressId);
        map.put("grouponPrice", grouponPrice);
        map.put("couponPrice", couponPrice);
        map.put("availableCouponLength", userAvailableCoupons.size());
        map.put("freightPrice", freightPrice);
        return BaseRespVo.ok(map);
    }

    @PostMapping("update")
    public BaseRespVo update(@RequestBody Map map) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            BaseRespVo baseRespVo = new BaseRespVo();
            baseRespVo.setErrno(501);
            baseRespVo.setErrmsg("请先登录");
            return baseRespVo;
        }
        Integer productId = (Integer) map.get("productId");
        Integer goodsId = (Integer) map.get("goodsId");
        Integer number = (Integer) map.get("number");
        Integer id = (Integer) map.get("id");//这个id实际就是cartId
        wxCartService.updateCartById(id, number);
        BaseRespVo respVo = BaseRespVo.ok(null);
        respVo.setErrmsg("成功");
        return respVo;
    }

    @PostMapping("delete")
    public BaseRespVo delete(@RequestBody Map map) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            BaseRespVo baseRespVo = new BaseRespVo();
            baseRespVo.setErrno(501);
            baseRespVo.setErrmsg("请先登录");
            return baseRespVo;
        }
        ArrayList<Integer> productIds = (ArrayList<Integer>) map.get("productIds");
        Integer userId = UserIdUtil.getUserIdFromSubject();
        Integer delete = wxCartService.deleteCartByUserIdAndProductIds(userId, productIds);
        if (delete == 0) {
            return BaseRespVo.invalidData("商品不存在");
        }
        HashMap<String, Object> stringObjectHashMap = this.queryCartById(userId);
        BaseRespVo respVo = BaseRespVo.ok(stringObjectHashMap);
        respVo.setErrmsg("成功");
        return respVo;
    }

    /**
     * 根据传过来的参数在cart里新增一行,这里新增默认是checked=true的,
     *
     * @param map
     * @return
     */
    @PostMapping("fastadd")
    public BaseRespVo fastadd(@RequestBody Map map) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            BaseRespVo baseRespVo = new BaseRespVo();
            baseRespVo.setErrno(501);
            baseRespVo.setErrmsg("请先登录");
            return baseRespVo;
        }
        Integer userId = UserIdUtil.getUserIdFromSubject();
        Integer goodsId = (Integer) map.get("goodsId");
        Integer number = (Integer) map.get("number");
        Integer productId = (Integer) map.get("productId");
        MarketCart marketCart = wxCartService.queryCartByGoodsIdAndProductId(goodsId, productId);
        marketCart.setUserId(userId);
        marketCart.setNumber(number);
        marketCart.setChecked(true);
        Date date = new Date();
        marketCart.setAddTime(date);
        marketCart.setUpdateTime(date);
        marketCart.setDeleted(false);
        Integer cartId = wxCartService.addCartByMarketCart(marketCart);
        return BaseRespVo.ok(cartId);
    }
}
